package dyyx.util;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import dyyx.dto.DubboNode;
import dyyx.dto.DubboServiceInfo;
import dyyx.dto.NodeData;

public abstract class DubboUtil {
	
	private static final String DUBBO_PATH = "/dubbo";
	
	
	public static String getProviderPath(String service){
		return DUBBO_PATH+"/"+service+"/providers";
	}
	
	public static String getConsumersPath(String service){
		return DUBBO_PATH+"/"+service+"/consumers";
	}
	
	public static String getService(String s){
		if(CommUtil.isBlank(s)){
			return null;
		}
		// /dubbo/a.b.c
		int index = s.lastIndexOf("/");
		if(index<0){
			return null;
		}
		
		 
		return s.substring(index + 1);
	}
	
	public static List<NodeData> getAllServices()throws Exception{
		return ClientUtil.getChildData(DUBBO_PATH);
	}
	
	
	
	
	public static List<NodeData> getProviders(String service)throws Exception{
		if(CommUtil.isBlank(service)){
			return null;
		}
		String path = getProviderPath(service);
		return ClientUtil.getChildData(path);
	}
	
	public static  List<NodeData> getConsumers(String service)throws Exception{
		if(CommUtil.isBlank(service)){
			return null;
		}
		String path = getConsumersPath(service);

		return ClientUtil.getChildData(path);
	}
	
	
	public static DubboServiceInfo getServiceInfo(String service)throws Exception{
		if(CommUtil.isBlank(service)){
			return null;
		}
		
		DubboServiceInfo info = new DubboServiceInfo();
		 info.service = service;
		 
		 try{
		     info.consumers = getConsumers(service);
		 }catch(Exception e){
			 if(isNoNodeException(e)){
				 
			 }else{
				 throw e;
			 }
		 }
		 try{

		     info.providers = getProviders(service);
		 
		 }catch(Exception e){
			 if(isNoNodeException(e)){
				 
			 }else{
				 throw e;
			 }
		 }
		 
		 build(info);
		 
		 return info;
	}

	
	
	public static List<DubboServiceInfo> getAllServiceInfo()throws Exception{
		 List<NodeData> nodes =  getAllServices();
		 if(nodes==null || nodes.isEmpty()){
			 return null;
		 }
		 String path = null;
		 String service = null;
		 List<DubboServiceInfo> list = new ArrayList<DubboServiceInfo>();
		 for(NodeData node:nodes){
			 path = node.path;
			 service = getService(path);
			 if(CommUtil.isBlank(service)){
				 continue;
			 }
			 DubboServiceInfo info  = getServiceInfo(service);
			 if(info==null){
				 continue;
			 }
			 
			
			 
			 list.add(info);
			 
		 }
		 
		 // build(list);
			
		return list;
	}
	
	
	private static boolean isNoNodeException(Throwable e){
		return e.toString().contains("NoNodeException");
	}
	
	
	private static List<DubboNode> buildDubboNode(List<NodeData> list){
		if(list==null || list.isEmpty()){
			return null;
		}
		List<DubboNode> list2 = new ArrayList<DubboNode>();

		for(NodeData item:list){
			DubboNode dubboNode = buildDubboNode(item);
			if(dubboNode==null){
				continue;
			}
			list2.add(dubboNode);
		}
		return list2;
	}
	
	private static DubboNode buildDubboNode(NodeData data){
		if(data==null){
			return null;
		}
		String path = data.path;
		path = CommUtil.urlDecode(path);
		if(CommUtil.isBlank(path)){
			return null;
		}
		
		int index = path.indexOf("?");
		if(index<=0){
			return null;
		}
		String str = path.substring(index+1);
		if(CommUtil.isBlank(str)){
			return null;
		}
		
		Map<String,String> map = CommUtil.queryString2map(str);
		if(map==null || map.isEmpty()){
			return null;
		}
		//
		// String service = map.get("service");
	    String application = map.get("application");
	    String version = map.get("version");
	    /*
	    if(CommUtil.isBlank(service)){
			return null;
		}
	    if(CommUtil.isBlank(application)){
			return null;
		}
		*/
	    //    providerIpAndPort   consumerIp
	    
	    
	    /*
	    if(CommUtil.isBlank(version)){
			return null;
		}
		*/
	    if(version==null){
	    	version = "";
	    }
	    
	    String group = map.get("group");
	    if(group==null){
	    	group = "";
	    }
	    
	    
	    
	    DubboNode dubboNode = new DubboNode();
	    dubboNode.path = path;
	    // dubboNode.service = service;
	    dubboNode.application = application;
	    dubboNode.version = version;
	    dubboNode.group = group;

	    
	    dubboNode.providerIpAndPort = parseProviderIpAndPort(path);
	    dubboNode.consumerIp = parseConsumerIp(path);
	    
		return dubboNode;
	}
	
	private static String parseProviderIpAndPort(String path){
		// /dubbo://10.60.21.40:20877/
		
		return CommUtil.fetchString(path, "/dubbo://", "/");
	}
	
	private static String parseConsumerIp(String path){
		// /consumer://10.60.0.25/
		
		return CommUtil.fetchString(path, "/consumer://", "/");
	}
	
	
	private static void build(DubboServiceInfo info){
		List<NodeData> providers = info.providers;
		List<NodeData> consumers = info.consumers;
		info.consumersOfDubboNode = buildDubboNode(consumers);
		info.providersOfDubboNode = buildDubboNode(providers);
		
		///
		
		
		
	}
	

	
	
	private static void build(List<DubboServiceInfo> list){
		if(list==null || list.isEmpty()){
			return;
		}
		for(DubboServiceInfo item:list){
			build(item);
		}
		
	}
	
	public static void main(String[] args) throws Exception {
		String path = "/dubbo/a.b.c";
		System.out.println(getService(path));
		
		String str = "a=1&b=2";
		Map<String,String> map = CommUtil.queryString2map(str);
		System.out.println(map);
		
		//
		String zk = "10.57.34.20:2181";
		ClientUtil.connect(zk);
		long start = System.currentTimeMillis();
		List<DubboServiceInfo> list = getAllServiceInfo();
		long end = System.currentTimeMillis();
		long time = end - start;

		System.out.println("size="+list.size());
		System.out.println("time="+time);


				
		
	}

}
